package mbp.gui.panels;

import javax.swing.DefaultCellEditor;
import javax.swing.JComboBox;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;

import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Iterator;
import java.util.TimeZone;

import javax.swing.JTextField;
import javax.swing.JLabel;
import javax.swing.table.DefaultTableModel;

import mbp.base.DateString;
import mbp.base.FeatureType;
import mbp.base.GuiFunction;
import mbp.base.ResourceType;
import mbp.core.Resource;
import mbp.exceptions.InvalidFeatureNameException;
import mbp.exceptions.InvalidFeatureTypeException;
import mbp.exceptions.InvalidFeatureValueException;
import mbp.gui.base.EachRowEditor;
import mbp.gui.base.IListPanel;
import mbp.message.ObjectBuilder;

import org.apache.log4j.Logger;
import javax.swing.border.TitledBorder;
import javax.swing.JButton;

public class ResourceEditPanel extends JPanel implements ActionListener
{
	private JTextField txtValidDate;
	private JTextField txtOwner;
	private JTextField txtType;
	private JTextField txtUUID;
	
	private JButton btnSave;
	private JButton btnAddH;
	
	private Resource resource;
	private mbp.message.resource rci;
	
	private JTable dt;
	private DefaultTableModel model;
	
	private IListPanel listPanel; 
	
	private Logger logger = Logger.getLogger(this.getClass());

	/**
	 * Create the panel.
	 */
	private ResourceEditPanel() {
		setBorder(new TitledBorder(null, "Resource", TitledBorder.LEADING, TitledBorder.TOP, null, null));
		setLayout(null);
		
		model = new DefaultTableModel();
		model.addColumn("Feature Name");
		model.addColumn("Feature Type");
		model.addColumn("Feature Value");
		
		dt = new JTable(model);
		dt.setFillsViewportHeight(true);
		
		JScrollPane scrollPane = new JScrollPane(dt);
		scrollPane.setBounds(10, 160, 286, 95);
		add(scrollPane);
		
		txtValidDate = new JTextField();
		txtValidDate.setColumns(10);
		txtValidDate.setBounds(10, 129, 170, 20);
		add(txtValidDate);
		
		JLabel label = new JLabel("Valid date");
		label.setBounds(186, 135, 96, 14);
		add(label);
		
		JLabel label_1 = new JLabel("Owner");
		label_1.setBounds(186, 104, 96, 14);
		add(label_1);
		
		txtOwner = new JTextField();
		txtOwner.setText((String) null);
		txtOwner.setColumns(10);
		txtOwner.setBounds(10, 98, 170, 20);
		add(txtOwner);
		
		txtType = new JTextField();
		txtType.setText((String) null);
		txtType.setEditable(false);
		txtType.setColumns(10);
		txtType.setBounds(10, 67, 170, 20);
		add(txtType);
		
		JLabel label_2 = new JLabel("Type");
		label_2.setBounds(186, 73, 96, 14);
		add(label_2);
		
		txtUUID = new JTextField();
		txtUUID.setText((String) null);
		txtUUID.setEditable(false);
		txtUUID.setColumns(10);
		txtUUID.setBounds(10, 36, 286, 20);
		add(txtUUID);
		
		JLabel label_3 = new JLabel("UUID");
		label_3.setBounds(10, 21, 46, 14);
		add(label_3);
		
		btnSave = new JButton("Save");
		btnSave.setBounds(207, 266, 89, 23);
		add(btnSave);
		btnSave.addActionListener(this);
		
		btnAddH = new JButton("Add 1 h");
		btnAddH.setBounds(108, 266, 89, 23);
		add(btnAddH);
		btnAddH.addActionListener(this);

	}
	
	public ResourceEditPanel(GuiFunction guiFundtion, IListPanel listPanel) {
		this();
		switch(guiFundtion)
		{
		case EDITOR:
			break;
		case VIEWER:
			btnSave.setVisible(false);
			btnAddH.setVisible(false);
			txtValidDate.setEditable(false);
			txtOwner.setEditable(false);
			dt.setEnabled(false);
			break;
		}
		
		this.listPanel = listPanel;
	}
	
	@Override
	public void actionPerformed(ActionEvent e) 
	{
		if(e.getSource() == btnSave)
		{
			saveResource();
			if(this.listPanel != null)
			{
				this.listPanel.reloadList();
			}
		}
		
		if(e.getSource() == btnAddH)
		{
			DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");
			df.setTimeZone(TimeZone.getTimeZone("UTC"));
			Calendar calendar = Calendar.getInstance();
			calendar.add(Calendar.HOUR, 1);
			Date dt = calendar.getTime();
			String dts = df.format(dt);
			txtValidDate.setText(dts);
		}
		
	}
	
	
	public void clearResourceFields()
	{
		/**
		 * Wyczyszczenie tabeli
		 */
		for( int i = model.getRowCount() - 1; i >= 0; i-- )
		{
		    model.removeRow(i);
		}
		txtUUID.setText("");
		txtOwner.setText("");
		txtValidDate.setText("yyyy-MM-ddTHH:mm:ss.SSS");
	}
	
	private void saveResource()
	{
		if(resource != null)
		{
			resource.setOwner(txtOwner.getText());
			DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");
			df.setTimeZone(TimeZone.getTimeZone("UTC"));
			try {
				Date dt = df.parse(txtValidDate.getText());
				resource.setValidDate(dt);
			} catch (ParseException e2) {
				// TODO Auto-generated catch block
				logger.error("ParseException", e2);
			}
			
			for(int i = 0; i<model.getRowCount(); i++)
			{
				try 
				{
					String fKey = (String)model.getValueAt(i, 0);
					FeatureType fType = (FeatureType)model.getValueAt(i, 1);
					switch(fType)
					{
					case INT:
						Integer fValuei = Integer.parseInt((String)model.getValueAt(i, 2));
						resource.setFeatureValue(fKey, fValuei);
						break;
					case FLOAT:
						Float fValuef = Float.parseFloat((String)model.getValueAt(i, 2));
						resource.setFeatureValue(fKey, fValuef);
						break;
					case ENUM:
						String fValuee = (String)model.getValueAt(i, 2);							
						resource.setFeatureValue(fKey, fValuee);
						break;
					}
					
					//resource.SetFeatureValue((String)model.getValueAt(i, 0), model.getValueAt(i, 2));
				} 
				catch (InvalidFeatureNameException e1) 
				{
					// TODO Auto-generated catch block
					logger.error("InvalidFeatureNameException", e1);
				} 
				catch (InvalidFeatureTypeException e1) 
				{
					// TODO Auto-generated catch block
					logger.error("InvalidFeatureTypeException", e1);
				} 
				catch (InvalidFeatureValueException e1) 
				{
					// TODO Auto-generated catch block
					logger.error("InvalidFeatureValueException", e1);
				}
				catch (Exception e1)
				{
					logger.error("Exception", e1);					
				}
			}
		}
	}
	
	public void loadResourceInfo(mbp.message.resource rci)
	{
		this.rci = rci;
		ObjectBuilder obb = new ObjectBuilder();
		loadResource(obb.getResource(rci));
	}
	
	/**
	 * Laduje szczegoly zasobu do okna edycyjnego i ustawia zaladowany zasob jako aktywny
	 * @param res
	 */
	public void loadResource(Resource res)
	{
		this.resource = res;
		int rowsCount = 0;
		ResourceType resType = res.getType();
		
		txtUUID.setText(res.getUUID());
		txtType.setText(res.getType().getResourceTypeName());
		
		/**
		 * Wyczyszczenie tabeli
		 */
		for( int i = model.getRowCount() - 1; i >= 0; i-- )
		{
		    model.removeRow(i);
		}
		
		/**
		 * Utworzenie tabeli JTable dt pozwalajecej wrowadzic wartosci cech utworzonego zasobu
		 */
		Iterator it = res.getType().getFeaturesCollection().keySet().iterator();
		while (it.hasNext()) 
		{
			String key = (String)it.next();
			//System.out.println("f: " + key);
			//rowsCount = dt.getRowCount();
			try
			{
				FeatureType type = res.getFeatureType(key);
				Object ob = res.getFeatureValue(key);
				if(ob==null)
				{
					model.insertRow(rowsCount, new Object[]{key,  res.getFeatureType(key), null});
				}
				else
				{
					switch(type)
					{
					case INT:
						model.insertRow(rowsCount, new Object[]{key,  res.getFeatureType(key), ((Integer)ob).toString()});						
						break;
					case FLOAT:
						model.insertRow(rowsCount, new Object[]{key,  res.getFeatureType(key), ((Float)ob).toString()});
						break;
					default:
						model.insertRow(rowsCount, new Object[]{key,  res.getFeatureType(key), ob.toString()});
						break;
					}
				}
				
				rowsCount++;
			}
			catch (InvalidFeatureNameException ex) 
			{
				logger.error("InvalidFeatureNameException", ex);
			}
			catch (Exception ex)
			{
				logger.error("Exception", ex);					
			}
		}
		
		/**
		 * DLA TYPOW ENUM
		 * Modyfikacja komorek tabeli (danego wiersza) aby mozna bylo wyswietlic obiekt JComboBox
		 */
		EachRowEditor rowEditor = new EachRowEditor(dt);
		for(int i = 0; i<dt.getRowCount(); i++)
		{
			if(dt.getValueAt(i, 1) == FeatureType.ENUM)
			{
				/**
				 * Utworzenie obiektu JComboBox wartosci enum przylkadowego typu
				 * Obiekt ten zostanie umieszczony w tabeli
				 */
				JComboBox cmbTypesV = new JComboBox();
				//try 
				//{
					//Class cl = Class.forName(typeBuilder.GetEnumTypeName(resType.GetResourceTypeName(), (String)dt.getValueAt(i, 0)));
					//Enum[] ev = (Enum[])cl.getEnumConstants();
					
					String[] ev = resType.getEnumTypes().get((String)dt.getValueAt(i, 0)).getArray();
					
					for(String v: ev)
					{
						cmbTypesV.addItem(v);
					}
				//} catch (ClassNotFoundException e1) {
				//	e1.printStackTrace();
				//}
				
				
				//for(EnumValues v: EnumValues.values())
				//{
				//	cmbTypesV.addItem(v);
				//}
				rowEditor.setEditorAt(i, new DefaultCellEditor(cmbTypesV));
				
			
			}
			
			
		}
		dt.getColumn("Feature Value").setCellEditor(rowEditor);
		
		txtOwner.setText(res.getOwner());
		Date dt = res.getValidDate();
		if(dt!=null)
		{
		    txtValidDate.setText(DateString.DateToStr(dt));
		}
		else
		{
			txtValidDate.setText("yyyy-MM-ddTHH:mm:ss.SSS");
		}
		
		resource = res;
		//resourceType = res.GetType();
	}

}
